import ifcopenshell
import json
import os
from typing import Dict, Any, List
from datetime import datetime
from app.config import settings

class IFCService:
    """IFC文件处理服务类"""
    
    async def convert_ifc_to_json(self, file_path: str) -> Dict[str, Any]:
        """将IFC文件转换为JSON格式（异步包装）"""
        return process_ifc_file(file_path)
    
    def process_ifc_file(self, file_path: str) -> Dict[str, Any]:
        """处理IFC文件并返回JSON格式数据"""
        return process_ifc_file(file_path)

def process_ifc_file(file_path: str) -> Dict[str, Any]:
    """处理IFC文件并返回增强格式的JSON数据，包含详细的消防和结构分析"""
    try:
        start_time = datetime.now()

        ifc_file = ifcopenshell.open(file_path)

        # 提取项目信息
        project_info = extract_project_info(ifc_file)
        
        # 提取空间结构
        spatial_structure = extract_spatial_structure(ifc_file)
        
        # 提取建筑元素（包含详细信息）
        building_elements = extract_building_elements(ifc_file)
        
        # 提取消防分析信息
        fire_safety_analysis = extract_fire_safety_analysis(ifc_file, building_elements)
        
        # 提取门窗详细尺寸信息
        door_window_analysis = extract_door_window_analysis(building_elements)
        
        # 提取结构构件分析
        structural_analysis = extract_structural_analysis(building_elements)

        # 构建增强格式的结果
        result = {
            "metadata": {
                "conversion_date": datetime.now().isoformat(),
                "ifc_schema": ifc_file.schema,
                "source_file": os.path.basename(file_path),
                "element_count": len(building_elements),
                "analysis_version": "enhanced_v2.0"
            },
            "project_info": project_info,
            "spatial_structure": spatial_structure,
            "elements": building_elements,
            "analysis": {
                "fire_safety": fire_safety_analysis,
                "door_window_details": door_window_analysis,
                "structural_analysis": structural_analysis
            }
        }

        return result

    except Exception as e:
        raise Exception(f"IFC文件处理错误: {str(e)}")

def extract_project_info(ifc_file):
    """提取项目信息"""
    projects = ifc_file.by_type("IfcProject")
    if not projects:
        return {}

    project = projects[0]
    return {
        "name": getattr(project, "Name", ""),
        "description": getattr(project, "Description", ""),
        "object_type": getattr(project, "ObjectType", ""),
        "global_id": getattr(project, "GlobalId", "")
    }

def extract_spatial_structure(ifc_file):
    """提取空间结构信息"""
    structure = {
        "sites": [],
        "buildings": [],
        "storeys": []
    }

    # 提取场地
    for site in ifc_file.by_type("IfcSite"):
        structure["sites"].append({
            "name": getattr(site, "Name", ""),
            "global_id": getattr(site, "GlobalId", "")
        })

    # 提取建筑
    for building in ifc_file.by_type("IfcBuilding"):
        structure["buildings"].append({
            "name": getattr(building, "Name", ""),
            "global_id": getattr(building, "GlobalId", "")
        })

    # 提取楼层
    for storey in ifc_file.by_type("IfcBuildingStorey"):
        structure["storeys"].append({
            "name": getattr(storey, "Name", ""),
            "global_id": getattr(storey, "GlobalId", ""),
            "elevation": getattr(storey, "Elevation", 0)
        })

    return structure

def extract_building_elements(ifc_file):
    """提取建筑元素详细信息，包括关键属性"""
    elements = []
    element_types = [
        "IfcWall", "IfcDoor", "IfcWindow", "IfcSlab", 
        "IfcBeam", "IfcColumn", "IfcStair", "IfcRailing",
        "IfcCovering", "IfcCurtainWall", "IfcMember", "IfcPlate"
    ]

    for element_type in element_types:
        for element in ifc_file.by_type(element_type):
            element_data = {
                "GlobalId": getattr(element, "GlobalId", ""),
                "Name": getattr(element, "Name", ""),
                "Type": element_type,
                "ObjectType": getattr(element, "ObjectType", ""),
                "Tag": getattr(element, "Tag", ""),
                "Description": getattr(element, "Description", "")
            }
            
            # 提取几何信息
            geometry = extract_element_geometry(element)
            if geometry:
                element_data["Geometry"] = geometry
            
            # 从几何表示提取尺寸
            dimensions = extract_dimensions_from_geometry(element)
            if dimensions:
                if "Geometry" not in element_data:
                    element_data["Geometry"] = {}
                element_data["Geometry"].update(dimensions)
            
            # 提取详细属性集
            properties = extract_detailed_properties(element)
            if properties:
                element_data["Properties"] = properties
            
            # 提取材料信息
            materials = extract_material_info(element)
            if materials:
                element_data["Materials"] = materials
            
            # 提取类型属性
            type_properties = extract_type_properties(element)
            if type_properties:
                element_data["TypeProperties"] = type_properties
            
            # 提取所有关键属性到顶层
            key_properties = extract_key_properties(element, properties, dimensions)
            if key_properties:
                element_data.update(key_properties)

            elements.append(element_data)

    return elements

def extract_element_geometry(element):
    """提取元素几何信息"""
    geometry = {}
    
    # 提取基本几何属性
    if hasattr(element, "ObjectPlacement"):
        placement = element.ObjectPlacement
        if placement and hasattr(placement, "RelativePlacement"):
            relative_placement = placement.RelativePlacement
            if hasattr(relative_placement, "Location"):
                location = relative_placement.Location
                if hasattr(location, "Coordinates"):
                    geometry["Location"] = {
                        "X": location.Coordinates[0] if len(location.Coordinates) > 0 else 0,
                        "Y": location.Coordinates[1] if len(location.Coordinates) > 1 else 0,
                        "Z": location.Coordinates[2] if len(location.Coordinates) > 2 else 0
                    }
    
    # 提取尺寸信息
    if hasattr(element, "Representation"):
        representation = element.Representation
        if representation and hasattr(representation, "Representations"):
            for rep in representation.Representations:
                if rep.is_a("IfcShapeRepresentation"):
                    for item in rep.Items:
                        if item.is_a("IfcExtrudedAreaSolid") or item.is_a("IfcBoundingBox"):
                            if hasattr(item, "XDim"):
                                geometry["OverallWidth"] = item.XDim
                            if hasattr(item, "YDim"):
                                geometry["OverallHeight"] = item.YDim
                            if hasattr(item, "ZDim"):
                                geometry["OverallDepth"] = item.ZDim
    
    return geometry if geometry else None

def extract_detailed_properties(element):
    """提取详细属性信息，增强门、窗尺寸和承重构件耐火等级提取"""
    detailed_props = {}
    element_type = element.is_a()

    # 提取基础数量（IfcElementQuantity）
    base_quantities = extract_base_quantities(element)
    if base_quantities:
        detailed_props.update(base_quantities)

    # 提取类型属性（IfcRelDefinesByType）
    type_props = extract_type_properties(element)
    if type_props:
        detailed_props["TypeProperties"] = type_props

    # 提取门、窗和承重构件的特殊属性
    door_window_type_props = extract_type_properties_for_doors_windows(element)
    if door_window_type_props:
        detailed_props.update(door_window_type_props)

    # 从几何表示提取尺寸
    geom_dimensions = extract_dimensions_from_geometry(element)
    if geom_dimensions:
        # 合并几何尺寸，避免覆盖已有值
        for key, value in geom_dimensions.items():
            if key not in detailed_props or detailed_props[key] is None:
                detailed_props[key] = value

    # 提取属性集（IfcPropertySet & IfcElementQuantity）
    if hasattr(element, "IsDefinedBy"):
        for definition in element.IsDefinedBy:
            if definition.is_a("IfcRelDefinesByProperties"):
                property_set = definition.RelatingPropertyDefinition

                if property_set.is_a("IfcPropertySet"):
                    pset_name = property_set.Name
                    pset_properties = {}

                    for prop in property_set.HasProperties:
                        if prop.is_a("IfcPropertySingleValue"):
                            prop_name = prop.Name
                            prop_value = prop.NominalValue.wrappedValue if prop.NominalValue else None
                            pset_properties[prop_name] = prop_value

                            # 关键属性提升到顶层
                            prop_name_lower = str(prop_name).lower()

                            # 门、窗尺寸
                            if element_type in ["IfcDoor", "IfcWindow"]:
                                if any(keyword in prop_name_lower for keyword in ["width", "overallwidth", "openingwidth"]):
                                    if "OverallWidth" not in detailed_props:
                                        detailed_props["OverallWidth"] = prop_value
                                elif any(keyword in prop_name_lower for keyword in ["height", "overallheight", "openingheight"]):
                                    if "OverallHeight" not in detailed_props:
                                        detailed_props["OverallHeight"] = prop_value
                                elif any(keyword in prop_name_lower for keyword in ["depth", "thickness", "overalldepth"]):
                                    if "OverallDepth" not in detailed_props:
                                        detailed_props["OverallDepth"] = prop_value

                            # 承重构件耐火等级
                            if element_type in ["IfcWall", "IfcColumn", "IfcBeam", "IfcSlab"]:
                                if any(keyword in prop_name_lower for keyword in [
                                    "firerating", "fire_rating", "fireresistance", "fire_resistance",
                                    "耐火", "防火", "fireprotection", "fire_protection"
                                ]):
                                    if "FireRating" not in detailed_props:
                                        detailed_props["FireRating"] = prop_value

                            # 通用属性
                            if "thermaltransmittance" in prop_name_lower or "uvalue" in prop_name_lower:
                                if "ThermalTransmittance" not in detailed_props:
                                    detailed_props["ThermalTransmittance"] = prop_value

                    detailed_props[pset_name] = pset_properties

                elif property_set.is_a("IfcElementQuantity"):
                    quantity_name = property_set.Name
                    quantities = {}

                    for quantity in property_set.Quantities:
                        if quantity.is_a("IfcQuantityLength"):
                            qty_name = quantity.Name
                            qty_value = quantity.LengthValue
                            quantities[qty_name] = qty_value

                            # 映射关键尺寸属性
                            qty_name_lower = str(qty_name).lower()

                            # 门、窗尺寸
                            if element_type in ["IfcDoor", "IfcWindow"]:
                                if any(keyword in qty_name_lower for keyword in ["width", "openingwidth"]):
                                    if "OverallWidth" not in detailed_props:
                                        detailed_props["OverallWidth"] = qty_value
                                elif any(keyword in qty_name_lower for keyword in ["height", "openingheight"]):
                                    if "OverallHeight" not in detailed_props:
                                        detailed_props["OverallHeight"] = qty_value
                                elif any(keyword in qty_name_lower for keyword in ["thickness", "depth"]):
                                    if "OverallDepth" not in detailed_props:
                                        detailed_props["OverallDepth"] = qty_value

                            # 通用尺寸
                            elif "width" in qty_name_lower:
                                if "OverallWidth" not in detailed_props:
                                    detailed_props["OverallWidth"] = qty_value
                            elif "height" in qty_name_lower:
                                if "OverallHeight" not in detailed_props:
                                    detailed_props["OverallHeight"] = qty_value
                            elif "thickness" in qty_name_lower or "depth" in qty_name_lower:
                                if "OverallDepth" not in detailed_props:
                                    detailed_props["OverallDepth"] = qty_value
                            elif "length" in qty_name_lower:
                                if "OverallLength" not in detailed_props:
                                    detailed_props["OverallLength"] = qty_value

                        elif quantity.is_a("IfcQuantityArea"):
                            quantities[quantity.Name] = quantity.AreaValue

                        elif quantity.is_a("IfcQuantityVolume"):
                            quantities[quantity.Name] = quantity.VolumeValue

                        elif quantity.is_a("IfcQuantityCount"):
                            quantities[quantity.Name] = quantity.CountValue

                    detailed_props[quantity_name] = quantities

    # 从IfcRelDefinesByType中提取详细类型属性
    type_properties_detailed = extract_type_properties_detailed(element)
    if type_properties_detailed:
        detailed_props["TypeProperties"] = type_properties_detailed

    return detailed_props if detailed_props else None

def extract_type_properties_detailed(element):
    """提取详细的类型属性"""
    type_props = {}
    
    if hasattr(element, "IsTypedBy"):
        for type_rel in element.IsTypedBy:
            element_type = type_rel.RelatingType
            if element_type:
                type_props["TypeName"] = element_type.Name
                type_props["TypeDescription"] = element_type.Description if hasattr(element_type, "Description") else None
                
                # 提取类型属性集
                if hasattr(element_type, "HasPropertySets"):
                    for prop_set in element_type.HasPropertySets:
                        if prop_set.is_a("IfcPropertySet"):
                            set_props = {}
                            for prop in prop_set.HasProperties:
                                if prop.is_a("IfcPropertySingleValue"):
                                    prop_name = prop.Name
                                    prop_value = prop.NominalValue.wrappedValue if prop.NominalValue else None
                                    set_props[prop_name] = prop_value
                                    
                                    # 提取关键属性
                                    prop_name_lower = str(prop_name).lower()
                                    if "thermaltransmittance" in prop_name_lower or "uvalue" in prop_name_lower:
                                        type_props["ThermalTransmittance"] = prop_value
                                    elif "width" in prop_name_lower:
                                        type_props["OverallWidth"] = prop_value
                                    elif "height" in prop_name_lower:
                                        type_props["OverallHeight"] = prop_value
                                    elif "depth" in prop_name_lower or "thickness" in prop_name_lower:
                                        type_props["OverallDepth"] = prop_value
                            
                            type_props[prop_set.Name] = set_props
                
                # 提取类型数量信息
                if hasattr(element_type, "HasPropertySets"):
                    for prop_set in element_type.HasPropertySets:
                        if prop_set.is_a("IfcElementQuantity"):
                            quantities = {}
                            for quantity in prop_set.Quantities:
                                if quantity.is_a("IfcQuantityLength"):
                                    qty_name = quantity.Name
                                    qty_value = quantity.LengthValue
                                    
                                    # 映射关键尺寸属性
                                    qty_name_lower = str(qty_name).lower()
                                    if "width" in qty_name_lower:
                                        type_props["OverallWidth"] = qty_value
                                    elif "height" in qty_name_lower:
                                        type_props["OverallHeight"] = qty_value
                                    elif "thickness" in qty_name_lower or "depth" in qty_name_lower:
                                        type_props["OverallDepth"] = qty_value
                                    elif "length" in qty_name_lower:
                                        type_props["OverallLength"] = qty_value
                                
                                quantities[quantity.Name] = qty_value
                            
                            type_props[prop_set.Name] = quantities
    
    return type_props if type_props else None

def extract_key_properties(element, properties=None, dimensions=None):
    """提取关键属性到顶层结构，增强门、窗尺寸和耐火等级提取"""
    key_props = {}
    
    # 元素类型
    element_type = element.is_a()
    
    # 从几何和尺寸提取
    if dimensions:
        for key in ["OverallWidth", "OverallHeight", "OverallDepth", "OverallLength"]:
            if key in dimensions:
                key_props[key] = dimensions[key]
    
    # 从属性集提取
    if properties:
        # 搜索所有属性集中的关键属性
        for pset_name, pset_props in properties.items():
            if isinstance(pset_props, dict):
                for prop_name, prop_value in pset_props.items():
                    prop_name_lower = str(prop_name).lower()
                    
                    # 热传导系数
                    if "thermaltransmittance" in prop_name_lower or "uvalue" in prop_name_lower:
                        key_props["ThermalTransmittance"] = prop_value
                    
                    # 尺寸属性 - 增强门、窗尺寸提取
                    elif "width" in prop_name_lower and element_type in ["IfcDoor", "IfcWindow"]:
                        key_props["OverallWidth"] = prop_value
                    elif "height" in prop_name_lower and element_type in ["IfcDoor", "IfcWindow"]:
                        key_props["OverallHeight"] = prop_value
                    elif "overallwidth" in prop_name_lower:
                        key_props["OverallWidth"] = prop_value
                    elif "overallheight" in prop_name_lower:
                        key_props["OverallHeight"] = prop_value
                    elif "overalldepth" in prop_name_lower or "overallthickness" in prop_name_lower:
                        key_props["OverallDepth"] = prop_value
                    elif "overalllength" in prop_name_lower:
                        key_props["OverallLength"] = prop_value
                    
                    # 耐火等级 - 承重构件
                    elif "firerating" in prop_name_lower or "fire_rating" in prop_name_lower or "耐火" in str(prop_name):
                        key_props["FireRating"] = prop_value
                    elif "fireresistance" in prop_name_lower or "fire_resistance" in prop_name_lower:
                        key_props["FireRating"] = prop_value
                    elif "耐火等级" in str(prop_name) or "防火等级" in str(prop_name):
                        key_props["FireRating"] = prop_value
    
    # 从类型属性提取门、窗尺寸和耐火等级
    type_props = extract_type_properties_for_doors_windows(element)
    if type_props:
        if element_type in ["IfcDoor", "IfcWindow"]:
            if "OverallWidth" in type_props and "OverallWidth" not in key_props:
                key_props["OverallWidth"] = type_props["OverallWidth"]
            if "OverallHeight" in type_props and "OverallHeight" not in key_props:
                key_props["OverallHeight"] = type_props["OverallHeight"]
        
        # 承重构件的耐火等级
        if element_type in ["IfcWall", "IfcColumn", "IfcBeam", "IfcSlab"]:
            if "FireRating" in type_props and "FireRating" not in key_props:
                key_props["FireRating"] = type_props["FireRating"]
    
    # 从几何表示提取门、窗尺寸
    if element_type in ["IfcDoor", "IfcWindow"]:
        geo_dims = extract_door_window_dimensions(element)
        if geo_dims:
            if "OverallWidth" not in key_props and "OverallWidth" in geo_dims:
                key_props["OverallWidth"] = geo_dims["OverallWidth"]
            if "OverallHeight" not in key_props and "OverallHeight" in geo_dims:
                key_props["OverallHeight"] = geo_dims["OverallHeight"]
    
    # 从材料层厚度提取深度
    if hasattr(element, "HasAssociations"):
        for association in element.HasAssociations:
            if association.is_a("IfcRelAssociatesMaterial"):
                material = association.RelatingMaterial
                if material and material.is_a("IfcMaterialLayerSetUsage"):
                    layer_set = material.ForLayerSet
                    total_thickness = 0
                    for layer in layer_set.MaterialLayers:
                        total_thickness += layer.LayerThickness
                    key_props["OverallDepth"] = total_thickness
    
    return key_props if key_props else None

def extract_base_quantities(element):
    """提取基础数量信息，包括关键尺寸"""
    base_quantities = {}
    
    if hasattr(element, "IsDefinedBy"):
        for definition in element.IsDefinedBy:
            if definition.is_a("IfcRelDefinesByProperties"):
                property_set = definition.RelatingPropertyDefinition
                
                # 处理所有IfcElementQuantity
                if property_set.is_a("IfcElementQuantity"):
                    
                    for quantity in property_set.Quantities:
                        if quantity.is_a("IfcQuantityLength"):
                            qty_name = quantity.Name
                            qty_value = quantity.LengthValue
                            
                            # 标准化关键尺寸名称
                            qty_name_lower = str(qty_name).lower()
                            if "width" in qty_name_lower:
                                base_quantities["OverallWidth"] = qty_value
                            elif "height" in qty_name_lower:
                                base_quantities["OverallHeight"] = qty_value
                            elif "thickness" in qty_name_lower or "depth" in qty_name_lower:
                                base_quantities["OverallDepth"] = qty_value
                            elif "length" in qty_name_lower:
                                base_quantities["OverallLength"] = qty_value
                            else:
                                base_quantities[qty_name] = qty_value
                        
                        elif quantity.is_a("IfcQuantityArea"):
                            base_quantities[quantity.Name] = quantity.AreaValue
                        
                        elif quantity.is_a("IfcQuantityVolume"):
                            base_quantities[quantity.Name] = quantity.VolumeValue
                        
                        elif quantity.is_a("IfcQuantityCount"):
                            base_quantities[quantity.Name] = quantity.CountValue
    
    return base_quantities if base_quantities else None

def extract_dimensions_from_geometry(element):
    """从几何表示中提取尺寸信息"""
    dimensions = {}
    
    if hasattr(element, "Representation") and element.Representation:
        for representation in element.Representation.Representations:
            if representation.is_a("IfcShapeRepresentation"):
                for item in representation.Items:
                    if item.is_a("IfcExtrudedAreaSolid"):
                        # 从拉伸实体提取尺寸
                        if hasattr(item, "Depth"):
                            dimensions["OverallDepth"] = item.Depth
                        
                        # 从截面提取尺寸
                        profile = item.SweptArea
                        if profile:
                            if profile.is_a("IfcRectangleProfileDef"):
                                dimensions["OverallWidth"] = profile.XDim
                                dimensions["OverallHeight"] = profile.YDim
                            elif profile.is_a("IfcCircleProfileDef"):
                                dimensions["Diameter"] = profile.Radius * 2
                            elif profile.is_a("IfcIShapeProfileDef"):
                                dimensions["OverallWidth"] = profile.OverallWidth
                                dimensions["OverallHeight"] = profile.OverallDepth
                    
                    elif item.is_a("IfcBoundingBox"):
                        dimensions["OverallWidth"] = item.XDim
                        dimensions["OverallHeight"] = item.YDim
                        dimensions["OverallDepth"] = item.ZDim
    
    return dimensions if dimensions else None

def extract_material_info(element):
    """提取材料信息"""
    materials = []
    
    if hasattr(element, "HasAssociations"):
        for association in element.HasAssociations:
            if association.is_a("IfcRelAssociatesMaterial"):
                material = association.RelatingMaterial
                
                if material.is_a("IfcMaterial"):
                    material_info = {
                        "Name": material.Name,
                        "Category": material.Category if hasattr(material, "Category") else None,
                        "Description": material.Description if hasattr(material, "Description") else None
                    }
                    
                    # 提取材料属性
                    if hasattr(material, "HasProperties"):
                        material_props = {}
                        for prop_set in material.HasProperties:
                            if prop_set.is_a("IfcMaterialProperties"):
                                props = {}
                                for prop in prop_set.Properties:
                                    if prop.is_a("IfcPropertySingleValue"):
                                        props[prop.Name] = prop.NominalValue.wrappedValue if prop.NominalValue else None
                                material_props[prop_set.Name] = props
                        material_info["Properties"] = material_props
                    
                    materials.append(material_info)
                
                elif material.is_a("IfcMaterialLayerSetUsage"):
                    layer_set = material.ForLayerSet
                    layer_info = {
                        "LayerSetName": layer_set.LayerSetName if hasattr(layer_set, "LayerSetName") else None,
                        "Layers": []
                    }
                    
                    for layer in layer_set.MaterialLayers:
                        layer_data = {
                            "Material": layer.Material.Name if layer.Material else None,
                            "LayerThickness": layer.LayerThickness,
                            "IsVentilated": layer.IsVentilated if hasattr(layer, "IsVentilated") else None
                        }
                        layer_info["Layers"].append(layer_data)
                    
                    materials.append(layer_info)
    
    return materials if materials else None

def extract_type_properties(element):
    """提取类型属性"""
    type_props = {}
    
    if hasattr(element, "IsTypedBy"):
        for type_rel in element.IsTypedBy:
            element_type = type_rel.RelatingType
            if element_type:
                type_props["TypeName"] = element_type.Name
                type_props["TypeDescription"] = element_type.Description if hasattr(element_type, "Description") else None
                
                # 提取类型属性集
                if hasattr(element_type, "HasPropertySets"):
                    for prop_set in element_type.HasPropertySets:
                        if prop_set.is_a("IfcPropertySet"):
                            set_props = {}
                            for prop in prop_set.HasProperties:
                                if prop.is_a("IfcPropertySingleValue"):
                                    set_props[prop.Name] = prop.NominalValue.wrappedValue if prop.NominalValue else None
                            type_props[prop_set.Name] = set_props
    
    return type_props if type_props else None

def extract_type_properties_for_doors_windows(element):
    """专门提取门、窗类型属性，包括尺寸和耐火等级"""
    type_props = {}
    
    if hasattr(element, "IsTypedBy"):
        for type_rel in element.IsTypedBy:
            element_type = type_rel.RelatingType
            if element_type:
                # 提取类型属性集
                if hasattr(element_type, "HasPropertySets"):
                    for prop_set in element_type.HasPropertySets:
                        if prop_set.is_a("IfcPropertySet"):
                            for prop in prop_set.HasProperties:
                                if prop.is_a("IfcPropertySingleValue"):
                                    prop_name = prop.Name
                                    prop_value = prop.NominalValue.wrappedValue if prop.NominalValue else None
                                    
                                    prop_name_lower = str(prop_name).lower()
                                    
                                    # 门、窗尺寸
                                    if "width" in prop_name_lower or "overallwidth" in prop_name_lower:
                                        type_props["OverallWidth"] = prop_value
                                    elif "height" in prop_name_lower or "overallheight" in prop_name_lower:
                                        type_props["OverallHeight"] = prop_value
                                    elif "depth" in prop_name_lower or "thickness" in prop_name_lower:
                                        type_props["OverallDepth"] = prop_value
                                    
                                    # 耐火等级
                                    elif "firerating" in prop_name_lower or "fire_rating" in prop_name_lower:
                                        type_props["FireRating"] = prop_value
                                    elif "fireresistance" in prop_name_lower or "fire_resistance" in prop_name_lower:
                                        type_props["FireRating"] = prop_value
                                    elif "耐火" in str(prop_name) or "防火" in str(prop_name):
                                        type_props["FireRating"] = prop_value
                        
                        # 类型数量信息
                        elif prop_set.is_a("IfcElementQuantity"):
                            for quantity in prop_set.Quantities:
                                if quantity.is_a("IfcQuantityLength"):
                                    qty_name = quantity.Name
                                    qty_value = quantity.LengthValue
                                    
                                    qty_name_lower = str(qty_name).lower()
                                    if "width" in qty_name_lower:
                                        type_props["OverallWidth"] = qty_value
                                    elif "height" in qty_name_lower:
                                        type_props["OverallHeight"] = qty_value
                                    elif "depth" in qty_name_lower or "thickness" in qty_name_lower:
                                        type_props["OverallDepth"] = qty_value
    
    return type_props if type_props else None

def extract_door_window_dimensions(element):
    """专门从几何表示提取门、窗尺寸"""
    dimensions = {}
    
    if hasattr(element, "Representation") and element.Representation:
        for representation in element.Representation.Representations:
            if representation.is_a("IfcShapeRepresentation"):
                for item in representation.Items:
                    if item.is_a("IfcExtrudedAreaSolid"):
                        # 从截面提取门、窗尺寸
                        profile = item.SweptArea
                        if profile:
                            if profile.is_a("IfcRectangleProfileDef"):
                                dimensions["OverallWidth"] = profile.XDim
                                dimensions["OverallHeight"] = profile.YDim
                            elif hasattr(profile, "OverallWidth") and hasattr(profile, "OverallDepth"):
                                dimensions["OverallWidth"] = profile.OverallWidth
                                dimensions["OverallHeight"] = profile.OverallDepth
                    
                    elif item.is_a("IfcBoundingBox"):
                        dimensions["OverallWidth"] = item.XDim
                        dimensions["OverallHeight"] = item.YDim
                        dimensions["OverallDepth"] = item.ZDim
    
    return dimensions if dimensions else None

def extract_fire_safety_analysis(ifc_file, building_elements):
    """提取消防分析信息，包括防火等级、疏散通道等"""
    fire_analysis = {
        "fire_rated_elements": [],
        "doors_and_windows": {
            "fire_rated_doors": [],
            "emergency_exits": [],
            "window_areas": []
        },
        "structural_fire_protection": {
            "walls": [],
            "columns": [],
            "beams": [],
            "slabs": []
        },
        "fire_compartments": [],
        "evacuation_routes": []
    }
    
    # 分析防火等级构件
    for element in building_elements:
        element_type = element.get("Type", "")
        
        # 防火等级分析
        fire_rating = element.get("FireRating") or element.get("FireRating", "")
        if fire_rating and str(fire_rating).strip():
            fire_rated_elem = {
                "GlobalId": element.get("GlobalId", ""),
                "Name": element.get("Name", ""),
                "Type": element_type,
                "FireRating": str(fire_rating),
                "Location": element.get("Geometry", {}).get("Location", {}),
                "Dimensions": {
                    "Width": element.get("OverallWidth"),
                    "Height": element.get("OverallHeight"),
                    "Depth": element.get("OverallDepth")
                }
            }
            
            # 分类存储
            if element_type in ["IfcWall", "IfcColumn", "IfcBeam", "IfcSlab"]:
                if element_type == "IfcWall":
                    fire_analysis["structural_fire_protection"]["walls"].append(fire_rated_elem)
                elif element_type == "IfcColumn":
                    fire_analysis["structural_fire_protection"]["columns"].append(fire_rated_elem)
                elif element_type == "IfcBeam":
                    fire_analysis["structural_fire_protection"]["beams"].append(fire_rated_elem)
                elif element_type == "IfcSlab":
                    fire_analysis["structural_fire_protection"]["slabs"].append(fire_rated_elem)
                
                fire_analysis["fire_rated_elements"].append(fire_rated_elem)
    
    # 分析门窗消防特性
    for element in building_elements:
        element_type = element.get("Type", "")
        
        if element_type == "IfcDoor":
            door_info = {
                "GlobalId": element.get("GlobalId", ""),
                "Name": element.get("Name", ""),
                "Width": element.get("OverallWidth"),
                "Height": element.get("OverallHeight"),
                "FireRating": element.get("FireRating", ""),
                "Location": element.get("Geometry", {}).get("Location", {}),
                "Properties": element.get("Properties", {})
            }
            
            # 判断是否为防火门
            fire_rating = str(element.get("FireRating", "")).lower()
            if any(keyword in fire_rating for keyword in ["防火", "fire", "防火门", "fire door"]):
                fire_analysis["doors_and_windows"]["fire_rated_doors"].append(door_info)
            
            # 判断是否为紧急出口
            name = str(element.get("Name", "")).lower()
            if any(keyword in name for keyword in ["exit", "emergency", "疏散", "安全出口"]):
                fire_analysis["doors_and_windows"]["emergency_exits"].append(door_info)
        
        elif element_type == "IfcWindow":
            window_info = {
                "GlobalId": element.get("GlobalId", ""),
                "Name": element.get("Name", ""),
                "Width": element.get("OverallWidth"),
                "Height": element.get("OverallHeight"),
                "FireRating": element.get("FireRating", ""),
                "Location": element.get("Geometry", {}).get("Location", {}),
                "Area": None
            }
            
            # 计算窗户面积
            width = element.get("OverallWidth")
            height = element.get("OverallHeight")
            if width and height:
                window_info["Area"] = float(width) * float(height)
            
            fire_analysis["doors_and_windows"]["window_areas"].append(window_info)
    
    return fire_analysis

def extract_door_window_analysis(building_elements):
    """提取门窗详细尺寸和规格信息"""
    door_window_analysis = {
        "doors": {
            "total_count": 0,
            "by_type": {},
            "size_distribution": [],
            "fire_rated_count": 0,
            "emergency_exit_count": 0
        },
        "windows": {
            "total_count": 0,
            "by_type": {},
            "size_distribution": [],
            "total_area": 0,
            "fire_rated_count": 0
        },
        "detailed_listings": []
    }
    
    doors = []
    windows = []
    
    for element in building_elements:
        element_type = element.get("Type", "")
        
        if element_type == "IfcDoor":
            door_info = {
                "GlobalId": element.get("GlobalId", ""),
                "Name": element.get("Name", ""),
                "Type": "Door",
                "Width": element.get("OverallWidth"),
                "Height": element.get("OverallHeight"),
                "Depth": element.get("OverallDepth"),
                "FireRating": element.get("FireRating", ""),
                "Location": element.get("Geometry", {}).get("Location", {}),
                "ObjectType": element.get("ObjectType", ""),
                "Materials": element.get("Materials", [])
            }
            
            # 计算门面积
            width = element.get("OverallWidth")
            height = element.get("OverallHeight")
            if width and height:
                door_info["Area"] = float(width) * float(height)
            else:
                door_info["Area"] = None
            
            # 判断是否为防火门
            fire_rating = str(element.get("FireRating", "")).lower()
            is_fire_rated = any(keyword in fire_rating for keyword in ["防火", "fire", "防火门", "fire door"])
            door_info["IsFireRated"] = is_fire_rated
            
            # 判断是否为紧急出口
            name = str(element.get("Name", "")).lower()
            is_emergency = any(keyword in name for keyword in ["exit", "emergency", "疏散", "安全出口"])
            door_info["IsEmergencyExit"] = is_emergency
            
            doors.append(door_info)
            door_window_analysis["detailed_listings"].append(door_info)
            
        elif element_type == "IfcWindow":
            window_info = {
                "GlobalId": element.get("GlobalId", ""),
                "Name": element.get("Name", ""),
                "Type": "Window",
                "Width": element.get("OverallWidth"),
                "Height": element.get("OverallHeight"),
                "Depth": element.get("OverallDepth"),
                "FireRating": element.get("FireRating", ""),
                "Location": element.get("Geometry", {}).get("Location", {}),
                "ObjectType": element.get("ObjectType", ""),
                "Materials": element.get("Materials", [])
            }
            
            # 计算窗户面积
            width = element.get("OverallWidth")
            height = element.get("OverallHeight")
            if width and height:
                window_info["Area"] = float(width) * float(height)
            else:
                window_info["Area"] = None
            
            # 判断是否为防火窗
            fire_rating = str(element.get("FireRating", "")).lower()
            is_fire_rated = any(keyword in fire_rating for keyword in ["防火", "fire", "防火窗", "fire window"])
            window_info["IsFireRated"] = is_fire_rated
            
            windows.append(window_info)
            door_window_analysis["detailed_listings"].append(window_info)
    
    # 统计分析
    door_window_analysis["doors"]["total_count"] = len(doors)
    door_window_analysis["windows"]["total_count"] = len(windows)
    
    # 门的分类统计
    for door in doors:
        door_type = door.get("ObjectType", "Unknown")
        if door_type not in door_window_analysis["doors"]["by_type"]:
            door_window_analysis["doors"]["by_type"][door_type] = 0
        door_window_analysis["doors"]["by_type"][door_type] += 1
        
        if door.get("IsFireRated", False):
            door_window_analysis["doors"]["fire_rated_count"] += 1
        
        if door.get("IsEmergencyExit", False):
            door_window_analysis["doors"]["emergency_exit_count"] += 1
    
    # 窗户分类统计
    for window in windows:
        window_type = window.get("ObjectType", "Unknown")
        if window_type not in door_window_analysis["windows"]["by_type"]:
            door_window_analysis["windows"]["by_type"][window_type] = 0
        door_window_analysis["windows"]["by_type"][window_type] += 1
        
        if window.get("IsFireRated", False):
            door_window_analysis["windows"]["fire_rated_count"] += 1
        
        area = window.get("Area", 0) or 0
        door_window_analysis["windows"]["total_area"] += area
    
    return door_window_analysis

def extract_structural_analysis(building_elements):
    """提取结构构件分析，包括承重构件的详细规格"""
    structural_analysis = {
        "load_bearing_elements": {
            "walls": [],
            "columns": [],
            "beams": [],
            "slabs": [],
            "foundations": []
        },
        "fire_protection_summary": {
            "total_elements": 0,
            "fire_rated_elements": 0,
            "fire_rating_distribution": {}
        },
        "material_summary": {
            "by_material": {},
            "by_element_type": {}
        },
        "dimension_summary": {
            "walls": {"thickness_range": [], "height_range": []},
            "columns": {"size_range": [], "height_range": []},
            "beams": {"size_range": [], "length_range": []},
            "slabs": {"thickness_range": [], "area_range": []}
        }
    }
    
    load_bearing_types = ["IfcWall", "IfcColumn", "IfcBeam", "IfcSlab", "IfcFooting", "IfcPile"]
    
    for element in building_elements:
        element_type = element.get("Type", "")
        
        if element_type in load_bearing_types:
            elem_info = {
                "GlobalId": element.get("GlobalId", ""),
                "Name": element.get("Name", ""),
                "Type": element_type,
                "Dimensions": {
                    "Width": element.get("OverallWidth"),
                    "Height": element.get("OverallHeight"),
                    "Depth": element.get("OverallDepth"),
                    "Length": element.get("OverallLength")
                },
                "FireRating": element.get("FireRating", ""),
                "Location": element.get("Geometry", {}).get("Location", {}),
                "Materials": element.get("Materials", []),
                "Properties": element.get("Properties", {})
            }
            
            # 分类存储
            if element_type == "IfcWall":
                structural_analysis["load_bearing_elements"]["walls"].append(elem_info)
            elif element_type == "IfcColumn":
                structural_analysis["load_bearing_elements"]["columns"].append(elem_info)
            elif element_type == "IfcBeam":
                structural_analysis["load_bearing_elements"]["beams"].append(elem_info)
            elif element_type == "IfcSlab":
                structural_analysis["load_bearing_elements"]["slabs"].append(elem_info)
            elif element_type in ["IfcFooting", "IfcPile"]:
                structural_analysis["load_bearing_elements"]["foundations"].append(elem_info)
            
            # 统计防火等级
            structural_analysis["fire_protection_summary"]["total_elements"] += 1
            fire_rating = str(element.get("FireRating", "")).strip()
            if fire_rating:
                structural_analysis["fire_protection_summary"]["fire_rated_elements"] += 1
                
                if fire_rating not in structural_analysis["fire_protection_summary"]["fire_rating_distribution"]:
                    structural_analysis["fire_protection_summary"]["fire_rating_distribution"][fire_rating] = 0
                structural_analysis["fire_protection_summary"]["fire_rating_distribution"][fire_rating] += 1
            
            # 材料统计
            materials = element.get("Materials", [])
            if materials:
                for material in materials:
                    material_name = material.get("Name", "Unknown")
                    if material_name not in structural_analysis["material_summary"]["by_material"]:
                        structural_analysis["material_summary"]["by_material"][material_name] = 0
                    structural_analysis["material_summary"]["by_material"][material_name] += 1
            
            # 按类型统计
            if element_type not in structural_analysis["material_summary"]["by_element_type"]:
                structural_analysis["material_summary"]["by_element_type"][element_type] = 0
            structural_analysis["material_summary"]["by_element_type"][element_type] += 1
    
    return structural_analysis

def save_json_result(data: Dict[str, Any], original_filename: str) -> str:
    """保存JSON结果到文件"""
    import uuid
    from pathlib import Path

    # 生成输出文件名
    output_filename = f"{Path(original_filename).stem}_{uuid.uuid4().hex[:8]}.json"
    output_path = settings.OUTPUT_DIR / output_filename

    # 保存文件
    with open(output_path, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

    return str(output_path)